package demo;

import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.general.find.PdfTextFind;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;
import demo.bean.KzzJcGg;
import io.swagger.annotations.ApiModel;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;

/**
 * @Author: MI
 * @Date: 2022/2/24/0:30
 * @Description:
 */
@ApiModel("可转债减持")
public class KzzJc {
    /**
     * 解析PDF
     * 读取PDF为text解析
     *
     * @param pdfPath PDF文件路径
     * @return KzzJcGg
     */
    public static KzzJcGg parsePdf(String pdfPath, KzzJcGg kzzJcgg) {
        PdfDocument pdfDoc = new PdfDocument();
        pdfDoc.loadFromFile(pdfPath);
        ///////////////////获取可转债code name/////////////////////////
        //遍历文档页面|只需要第一页就可以获取名字
        PdfPageBase pdfPageBase = pdfDoc.getPages().get(0);
        PdfTextFind[] finds = pdfPageBase.findText("代码").getFinds();
        //多次循环只能最后一次，因为|https://cdn.jsdelivr.net/gh/qianlicao51/files@main/img/202202240009380.png
        String kzzCode = "";
        String kzzName = "";
        for (PdfTextFind find : finds) {
            String lineText = find.getLineText();
            lineText = StringUtils.trimToEmpty(lineText);
            //将 " 债券代码：113627          债券简称：太平转债"  更改为 “债券代码|113627          债券简称|太平转债”
            lineText = StringUtils.replaceEach(lineText, new String[]{":", "："}, new String[]{"|", "|"});
            //有些是 “债券代码” ，少部分是 "转债代码"
            if (StringUtils.startsWithAny(lineText, "债券代码", "转债代码")) {
                // 从中提取 可转债代码和名称
                kzzCode = StringUtils.substring(lineText, 5, 11);
                kzzName = StringUtils.substringAfter(lineText, "简称|");
            }
        }
        System.out.println("code=" + kzzCode + " name=" + kzzName);
        kzzJcgg.setKzzCode(kzzCode).setKzzName(kzzName);
        ///////////////////下面是计算减持具体信息//////////////////////
        /**
         * 不能直接按照文本读取，因为有些文本 持有人 换行，导致读取错误。先按照Table
         */
        //创建StringBuilder类的实例
        StringBuilder builder = new StringBuilder();
        //创建PdfTableExtractor类的对象
        PdfTableExtractor extractor = new PdfTableExtractor(pdfDoc);
        //遍历每一页
        boolean isTxt = false;
        for (int page = 0; page < pdfDoc.getPages().getCount(); page++) {
            //提取页面中的表格存入PdfTable[]数组
            PdfTable[] tableLists = extractor.extractTable(page);
            if (tableLists != null && tableLists.length > 0) {
                //遍历表格
                for (PdfTable table : tableLists) {
                    int row = table.getRowCount();//获取表格行
                    int column = table.getColumnCount();//获取表格列
                    //第一行是减持 部分不需要
                    for (int i = 0; i < row; i++) {
                        //第0,1,2 最后2列是需要的
                        for (int j = 0; j < column; j++) {
                            //获取表格中的文本内容
                            String text = table.getText(i, j);
                            //将获取的text写入StringBuilder容器
                            String replace = StringUtils.replaceEach(text, new String[]{"\n", ",", "%"}, new String[]{"", "", ""});
                            System.out.print(replace + " ");
                            builder.append(replace + "|");
                        }
                        System.out.println();
                        String[] split = builder.deleteCharAt(builder.length() - 1).toString().trim().split("\\|");
                        //第一列是持有人，如果获取到的是 数字，那就是 表格不完整，无法使用这种方式(同时排除合计)
                        if (StringUtils.isNumeric(split[0])) {
                            isTxt = true;
                            break;
                        }
                        //第一行是标题,需要跳过
                        if (i > 0) {
                            KzzJcGg.KzzJcItem kzzJcItem = new KzzJcGg.KzzJcItem().setCyr(split[0]).setCySl(split[1]).setCyZb(split[2]).setJcNum(split[3]).setJchSl(split[split.length - 2]).setJchZb(split[split.length - 1]);
                            System.out.println(kzzJcItem);
                            kzzJcgg.getItemList().add(kzzJcItem);
                        }
                        // builder.append(System.getProperty("line.separator"));
                        builder.setLength(0);
                    }
                }
            }
        }
        //////////////////////
        if (isTxt) {
            System.out.println(StringUtils.center("按照文本解析持有人", 51, "*"));
            StringBuilder sb = new StringBuilder();
            //遍历PDF页面，获取每个页面的文本并添加到StringBuilder对象
            for (int i = 0; i < pdfDoc.getPages().getCount(); i++) {
                sb.append(pdfDoc.getPages().get(i).extractText(false));
            }
            String[] split = StringUtils.substringAfter(sb.toString(), "持有人").split("\\r?\\n");
            System.out.println(StringUtils.substringAfter(sb.toString(), "持有人"));
            KzzJcGg.KzzJcItem kzzJcItem;
            for (String s : split) {
                //将 “李振国  7,214,630  14.43% 965,000 1.93% 6,249,630 12.50% ”
                // 替换为 "李振国  7214630  14.43 965000 1.93 6249630 12.50 "
                s = StringUtils.replaceEach(s, new String[]{",", "%"}, new String[]{"", ""}).trim();
                if (s.length() > 20) {
                    String[] cyrAndNum = StringUtils.split(s);
                    if (cyrAndNum.length >= 6) {
                        //至少包含 持有人名称|持有数量|持有比例|减持数量|减持后数量|减持后占比
                        if (!StringUtils.contains(cyrAndNum[0], "合计")) {
                            kzzJcItem = new KzzJcGg.KzzJcItem().setCyr(cyrAndNum[0]).setCySl(cyrAndNum[1]).setCyZb(cyrAndNum[2]).setJcNum(cyrAndNum[3]).setJchSl(cyrAndNum[cyrAndNum.length - 2]).setJchZb(cyrAndNum[cyrAndNum.length - 1]);
                            System.out.println(kzzJcItem);
                            kzzJcgg.getItemList().add(kzzJcItem);
                        }
                    }
                }
            }
        }
        return kzzJcgg;
    }

    @Test
    public void calc() {
        StringBuilder stringBuis = new StringBuilder("123");
        System.out.println(stringBuis.deleteCharAt(stringBuis.length() - 1));
        //清空 StringBuilder
        stringBuis.setLength(0);
        System.out.println(stringBuis);
    }

    @Test
    public void testParse() {
        //TODO 这个是测试方法
        String pdfPath = "D:/pdff/20220223/隆基股份：关于控股股东减持公司可转换公司债券的提示性公告.pdf";
        // pdfPath = "d:/金田铜业.pdf";
        pdfPath = "d:/隆基股份.pdf";
        // KzzJcGg kzzJcGg = parsePdf(pdfPath, new KzzJcGg());
        pdfPath = "D:/pdff/20220223/1212401799.PDF";
        pdfPath = "d:/佳力图.pdf";
        KzzJcGg kzzJcGg = KzzJcFinal.parsePdf(pdfPath, new KzzJcGg());
        System.out.println(StringUtils.center("-", 51, "*"));
        kzzJcGg.getItemList().forEach(System.out::println);
    }

    /**
     * "d:/金田铜业.pdf"; 不能按照 文本分割读取
     */
    @Test
    public void test() {
        String pdfPath = "d:/金田铜业.pdf";
        pdfPath = "d:/伟明环保.pdf";
        parsePdfTable(pdfPath);
    }

    /**
     * 按照表格获取，有时候，比如表格不完整(例如隆基的这种没有左右边框)
     *
     * @param pdfPath
     * @return
     */
    public KzzJcGg parsePdfTable(String pdfPath) {
        KzzJcGg kzzJcgg = new KzzJcGg();
        PdfDocument pdf = new PdfDocument();
        //加载PDF文档
        pdf.loadFromFile(pdfPath);
        ///////////////////获取可转债code name/////////////////////////
        //遍历文档页面|只需要第一页就可以获取名字
        PdfPageBase pdfPageBase = pdf.getPages().get(0);
        PdfTextFind[] finds = pdfPageBase.findText("代码").getFinds();

        //多次循环只能最后一次，因为|https://cdn.jsdelivr.net/gh/qianlicao51/files@main/img/202202240009380.png
        String kzzCode = "";
        String kzzName = "";
        for (PdfTextFind find : finds) {
            String lineText = find.getLineText();
            // System.out.println(lineText);
            lineText = StringUtils.trimToEmpty(lineText);
            //将 " 债券代码：113627          债券简称：太平转债"  更改为 “债券代码|113627          债券简称|太平转债”
            lineText = StringUtils.replaceEach(lineText, new String[]{":", "："}, new String[]{"|", "|"});
            //有些是 “债券代码” ，少部分是 "转债代码" | 还有的是  “可转债 代码” <可转债简称|旗滨转债>
            if (StringUtils.startsWithAny(lineText, "债券代码", "转债代码", "可转债代码")) {
                // 从中提取 可转债代码和名称
                kzzCode = StringUtils.substring(lineText, 5, 11);
                kzzName = StringUtils.substringAfter(lineText, "简称|");
            }
        }
        System.out.println("code=" + kzzCode + " name=" + kzzName);
        kzzJcgg.setKzzCode(kzzCode).setKzzName(kzzName);
        ///////////////////下面是计算减持具体信息//////////////////////
        //创建StringBuilder类的实例
        StringBuilder builder = new StringBuilder();
        //创建PdfTableExtractor类的对象
        PdfTableExtractor extractor = new PdfTableExtractor(pdf);
        //遍历每一页
        for (int page = 0; page < pdf.getPages().getCount(); page++) {
            //提取页面中的表格存入PdfTable[]数组
            PdfTable[] tableLists = extractor.extractTable(page);
            if (tableLists != null && tableLists.length > 0) {
                //遍历表格
                for (PdfTable table : tableLists) {
                    int row = table.getRowCount();//获取表格行
                    int column = table.getColumnCount();//获取表格列
                    //第一行是减持 部分不需要
                    for (int i = 0; i < row; i++) {
                        //第0,1,2 最后2列是需要的
                        for (int j = 0; j < column; j++) {
                            //获取表格中的文本内容
                            String text = table.getText(i, j);
                            //将获取的text写入StringBuilder容器
                            //replaceAll("//r|//n", "")
                            String replace = StringUtils.replaceEach(text, new String[]{"\n", ",", "%"}, new String[]{"", "", ""});
                            System.out.print(replace + " ");
                            builder.append(replace + "|");
                        }
                        System.out.println();
                        String lineStr = builder.deleteCharAt(builder.length() - 1).toString();
                        //
                        String[] split = lineStr.split("\\|");
                        KzzJcGg.KzzJcItem kzzJcItem = new KzzJcGg.KzzJcItem().setCyr(split[0]).setCySl(split[1]).setCyZb(split[2]).setJcNum(split[3]).setJchSl(split[split.length - 2]).setJchZb(split[split.length - 1]);
                        System.out.println(kzzJcItem);
                        kzzJcgg.getItemList().add(kzzJcItem);
                        // builder.append(System.getProperty("line.separator"));
                        builder.setLength(0);
                    }
                }
            }
        }

        return null;
    }


    /**
     * 读取文本内容
     */
    @Test
    public void getTextFrompDF() {
        //创建PdfDocument实例
        PdfDocument doc = new PdfDocument();
        //加载PDF文件
        String pdfPath = "d:/odf/1211457900.PDF";
        pdfPath = "d:/伟明环保.pdf";
        doc.loadFromFile(pdfPath);

        //创建StringBuilder实例
        StringBuilder sb = new StringBuilder();
        //遍历PDF页面，获取每个页面的文本并添加到StringBuilder对象
        for (int i = 0; i < doc.getPages().getCount(); i++) {
            sb.append(doc.getPages().get(i).extractText(false));
        }
        String[] split = StringUtils.substringAfter(sb.toString(), "持有人").split("\\r?\\n");
        KzzJcGg.KzzJcItem kzzJcItem;
        for (String s : split) {
            //将 “李振国  7,214,630  14.43% 965,000 1.93% 6,249,630 12.50% ”
            // 替换为 "李振国  7214630  14.43 965000 1.93 6249630 12.50 "

            s = StringUtils.replaceEach(s, new String[]{",", "%"}, new String[]{"", ""}).trim();
            System.out.println(s);
            if (s.length() > 20) {
                String[] cyrAndNum = StringUtils.split(s);
                if (cyrAndNum.length >= 6) {
                    //至少包含 持有人名称|持有数量|持有比例|减持数量|减持后数量|减持后占比
                    kzzJcItem = new KzzJcGg.KzzJcItem();
                    kzzJcItem.setCyr(cyrAndNum[0]).setCySl(cyrAndNum[1]).setCyZb(cyrAndNum[2]).setJcNum(cyrAndNum[3]).setJchSl(cyrAndNum[cyrAndNum.length - 2]).setJchZb(cyrAndNum[cyrAndNum.length - 1]);
                    System.out.println(kzzJcItem);
                }
            }
        }
    }

    @Test
    public void test4() {
        flag:
        for (int i = 1; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (i == 2) {
                    break flag;
                } else {
                    System.out.println("i=" + i + " ;j=" + j);
                }
            }
        }
        System.out.println("KzzJc.test4");
    }
}
